# -*- coding: utf-8 -*-

import base64
import datetime
import hashlib
import hmac
import json
import urllib
import uuid

import tornado.httpclient
from tornado import gen
from tornado.queues import Queue

# from apps.log import Logger
import  logging

class AliyunSMS(object):

    _sms_host = 'http://dysmsapi.aliyuncs.com/'
    _accessKeyId = ''
    _accessSecret = ''

    def __init__(self):
        pass

    def format_url(self, params):
        urls = ''
        for key, value in params:
            temp_url = '{}{}{}'.format(self.url_encode(str(key)), '=',
                                       self.url_encode(str(value)))
            urls = urls + temp_url + '&'
        return urls[:len(urls) - 1]

    def url_encode(self, args):
        r = urllib.parse.quote_plus(args).replace('+', '%20').replace(
            '*', '%2A').replace('%7E', '~')
        return r

    def sign(self, access_secret, prepare_str):
        access_secret = access_secret + '&'
        signature = base64.b64encode(
            hmac.new(access_secret.encode(),
                     prepare_str.encode(),
                     digestmod=hashlib.sha1).digest())
        sign = self.url_encode(signature)
        return sign

    async def send(self, PhoneNumbers, SignName, TemplateCode, TemplateParam):
        timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
        params = {
            'AccessKeyId': self._accessKeyId,
            'Action': 'SendSms',
            'Format': 'json',
            'RegionId': 'cn-hangzhou',
            'SignatureMethod': 'HMAC-SHA1',
            'SignatureNonce': str(uuid.uuid4()),
            'SignatureVersion': '1.0',
            'Timestamp': timestamp,
            'Version': '2017-05-25',
            'PhoneNumbers': PhoneNumbers,
            'SignName': SignName,
            'TemplateCode': TemplateCode,
            'TemplateParam': TemplateParam,
        }

        # 排序
        params = sorted(params.items(), key=lambda x: x[0])
        # 编码格式化url
        format_url = self.format_url(params)
        # 待签名
        builder_sign = 'GET' + '&' + self.url_encode(
            '/') + '&' + self.url_encode(format_url)
        # 签名
        signature = self.sign(self._accessSecret, builder_sign)
        # 最终请求URL
        final_url = self._sms_host + '?Signature=' + signature + '&' + format_url

        try:
            http_client = tornado.httpclient.AsyncHTTPClient()
            resp = await http_client.fetch(final_url)
            resp = json.loads(resp.body)
            logging.info(resp)
            return resp
        except Exception as e:
            logging.error(e)
            return None


class SmsQueue(object):
    _queque = Queue(0)

    @staticmethod
    async def start():
        while True:
            queque_msg = await SmsQueue._queque.get()
            try:
                await AliyunSMS().send(queque_msg['PhoneNumbers'],
                                       queque_msg['SignName'],
                                       queque_msg['TemplateCode'],
                                       queque_msg['TemplateParam'])
                await gen.sleep(0.01)
            finally:
                SmsQueue._queque.task_done()

    @staticmethod
    async def send(PhoneNumbers, SignName, TemplateCode, TemplateParam):
        msg = dict()
        msg['PhoneNumbers'] = PhoneNumbers
        msg['SignName'] = SignName
        msg['TemplateCode'] = TemplateCode
        msg['TemplateParam'] = TemplateParam
        await SmsQueue._queque.put(msg)


async def send_user_verifycode_sms(phone, code):
    await SmsQueue.send(phone, '空明物联网', 'SMS_183791528', {'code': code})
